﻿#region License
// MIT License
//
// Copyright(c) 2019-2025 ZhangYu
// https://gitee.com/zhangyu800/litebyte
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#endregion
#region Intro
// Purpose: Custom type configuration
// Author: ZhangYu
// CreateDate: 2019-10-10
// LastModifiedDate: 2025-02-22
#endregion
namespace LiteByte.Common {

    using System;
    using System.Collections.Generic;

    /// <summary>
    /// <para>LiteByte 类型和结构配置 | Type and type configurator </para>
    /// </summary>
    public static class ConfigData {

        #region Custom type
        private static List<TypeData> newTypes = null;
        private static Dictionary<string, TypeData> newMap = null;
        private static Dictionary<string, TypeData> typeMap = new Dictionary<string, TypeData>();

        /// <summary> 添加多个自定义类型 </summary>
        public static void AddTypes(List<TypeData> types) {
            if (newTypes == null) {
                newTypes = new List<TypeData>(types.Count);
                newMap = new Dictionary<string, TypeData>(types.Count);
            }
            newTypes.AddRange(types);
        }

        /// <summary> 清理所有自定义结构 | Clear all custom types </summary>
        public static void ClearTypes() {
            newTypes = null;
            newMap = null;
            typeMap.Clear();
        }

        /// <summary> 检查所有自定义类型的有效性 | Check the validity of all custom types </summary>
        public static void CheckAllTypes() {
            // 所有自定义类型先添加到临时HashMap中
            for (int i = 0; i < newTypes.Count; i++) {
                TypeData type = newTypes[i];
                newMap.Add(type.Name, type);
            }
            // 检查自定义类型的所有属性是否有效
            for (int i = 0; i < newTypes.Count; i++) {
                TypeData type = newTypes[i];
                List<FieldData> fields = type.Fields;
                for (int j = 0; j < fields.Count; j++) {
                    FieldData field = fields[j]; ;
                    TypeData fieldType = field.Type;
                    // 基本类型不需要验证
                    if (fieldType.IsBaseType) continue;
                    // 其他类型需要验证 验证后原来的缓存
                    TypeData validType = GetValidType(fieldType);
                    fields[j] = new FieldData(validType, field.Name);
                }
            }
            // 检查类型完毕 添加到缓存Map
            foreach(var item in newMap) {
                typeMap.Add(item.Key, item.Value);
            }
            newTypes = null;
            newMap = null;
        }

        /// <summary> 获取经过验证后的类型 </summary>
        private static TypeData GetValidType(TypeData type) {
            if (type.IsBaseType) return CommonUtil.GetBaseType(type.Name);
            if (type.IsGeneric) return GetValidGenericType(type);
            if (type.IsArray) return GetValidArrayType(type);
            return GetValidCustomType(type);
        }

        /// <summary> 获取经过验证后的泛型 </summary>
        private static TypeData GetValidGenericType(TypeData type) {
            TypeData cacheType = null;
            newMap.TryGetValue(type.Name, out cacheType);
            if (type.IsList || type.IsHashMap) {
                if (cacheType == null) {
                    // 验证所有泛型并生成新的Type
                    List<TypeData> generics = type.GenericTypes;
                    for (int i = 0; i < type.GenericTypes.Count; i++) {
                        generics[i] = GetValidType(generics[i]);
                    }
                    cacheType = new TypeData(type.Name, generics, type.IsList, type.IsHashMap);
                    // 添加缓存
                    newMap.Add(type.Name, cacheType);
                }
                return cacheType;
            } else {
                throw new Exception($"GetValidGenericType() error! Unsupported generic type:{type.Name}");
            }
        }

        /// <summary> 获取经过验证后的数组 </summary>
        private static TypeData GetValidArrayType(TypeData type) {
            TypeData cacheType = null;
            newMap.TryGetValue(type.Name, out cacheType);
            if (cacheType == null) {
                // 验证元素类型
                TypeData elementType = GetValidType(type.ElementType);
                if (elementType != null) {
                    cacheType = new TypeData(type.Name, elementType);
                    // 添加缓存
                    newMap.Add(type.Name, cacheType);
                } else {
                    throw new Exception($"GetValidArrayType() error! Invalid element type:{type.Name}");
                }
            }
            return cacheType;
        }

        /// <summary> 获取经过验证后的自定义类型 </summary>
        private static TypeData GetValidCustomType(TypeData type) {
            TypeData cacheType = null;
            newMap.TryGetValue(type.Name, out cacheType);
            if (cacheType == null) throw new Exception($"GetValidCustomType() error! Invalid custom type:{type.Name}");
            return cacheType;
        }

        /// <summary> 添加一个自定义类型 | Add a custom type </summary>
        /// <param name="lbType"> LB类型 | LBType</param>
        public static void AddType(TypeData lbType) {
            if (!typeMap.ContainsKey(lbType.Name)) {
                typeMap.Add(lbType.Name, lbType);
            } else {
                string error = "Custom type [{0}] already exists.";
                error = string.Format(error, lbType.Name);
                throw new ArgumentException(error);
            }
        }

        /// <summary> 获取已缓存的自定义结构体类型 | Get a cache LBType </summary>
        /// <param name="name"> LB结构体名称 | LB struct name</param>
        /// <returns> LBType or null</returns>
        public static TypeData GetType(string name) {
            TypeData type = CommonUtil.GetBaseType(name);
            if (type != null) return type;
            typeMap.TryGetValue(name, out type);
            return type;
        }

        /// <summary> 移除一个自定义类型 | Remove a custom type </summary>
        /// <param name="name"> 自定义类型名称 | Custom type name</param>
        public static void RemoveType(string name) {
            typeMap.Remove(name);
        }
        #endregion

    }

}